#include "main.h"
#include "DE15.h"
extern UART_HandleTypeDef huart2;
extern SDE15_UplinkFrame_FDBCK_Typdef g_t_uplfrm_fdbck;
/*UART Receive Buffer Size*/

/*Max number of Frame the DownlinkFrame FIFO can store */
#define DOWNLINKFRAME_FIFO_SIZE       5
SDE15_DownlinkFrame_Generic_TypeDef  g_arr_DownlinkFrame[DOWNLINKFRAME_FIFO_SIZE];
uint8_t g_DownlinkFrame_FIFO_Head = 0;
uint8_t g_DownlinkFrame_FIFO_End = 0;
uint8_t  g_UARTRecieveBuffer[UART_REC_BUFFER_SIZE];
uint16_t g_UARTRecieveBuffer_Head = 0;
uint16_t g_UARTRecieveBuffer_End = 0;

uint8_t g_IsNewFrame = 0;//'1'indicate that there may be a new frame
uint8_t g_NewFrame[DOWNLINKFRAME_SIZE];//store all the element of the new Frame
uint8_t g_FrameIndex = 0;//index reference to the New Frame element
/*When g_u8_RXDMAFIFO_Flush is set,RX DMA FIFO is flushed*/
uint8_t g_u8_RXDMAFIFO_Flush = 0;

uint8_t flag_enter_bootloder = 0;
uint8_t data[6]={0};
EDE15_STATE_Typedef g_e_de15_state = DE15_STATE_NON_SAMPLE;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{
    static uint32_t s_u32_recvbuf_index=0;
	
    if (huart->Instance == USART2) 
	{
        HAL_UART_Receive_IT(&huart2,data,1);
	
		g_UARTRecieveBuffer[s_u32_recvbuf_index++]=data[0];
		

		if(s_u32_recvbuf_index==UART_REC_BUFFER_SIZE)
		{
		   s_u32_recvbuf_index=0;
		}
		g_UARTRecieveBuffer_End=s_u32_recvbuf_index;
    }
    else
	{
           
    }
}
void SampleProcess(SDE15_DownlinkFrame_Generic_TypeDef DownlinkFrame)
{
	SDE15_DownlinkFrame_SampleCMD_TypeDef   SampleCMD_temp;
	SampleCMD_temp = *(SDE15_DownlinkFrame_SampleCMD_TypeDef*)(&DownlinkFrame);
	if(SampleCMD_temp.StartORStop == SAMPLE_START)
	{
		g_e_de15_state = DE15_STATE_SAMPLE;
	}
	else
	{
		g_e_de15_state = DE15_STATE_NON_SAMPLE;
	}
}

void ExtractFrameAndProcess(void)
{
  /*There is the situation when the FIFO has a few data but doesn't reach the FIFO thread,
  * we need to flush the FIFO
  */
	uint16_t CRCCode;
	SDE15_DownlinkFrame_Generic_TypeDef     DownlinkFrame;
	SDE15_DownlinkFrame_SampleCMD_TypeDef   SampleCMD_temp;
	while(g_UARTRecieveBuffer_Head != g_UARTRecieveBuffer_End)
	{
		uint16_t Index_Next = 0;
		Index_Next = (UART_REC_BUFFER_SIZE == (g_UARTRecieveBuffer_Head + 1))?0:( g_UARTRecieveBuffer_Head + 1);
		if((g_IsNewFrame != 1) && (0x68 == g_UARTRecieveBuffer[g_UARTRecieveBuffer_Head]))
		{
			g_IsNewFrame = 1;
			g_NewFrame[g_FrameIndex++] = g_UARTRecieveBuffer[g_UARTRecieveBuffer_Head];
		}
		else if(1 == g_IsNewFrame)
		{
			g_NewFrame[g_FrameIndex++] = g_UARTRecieveBuffer[g_UARTRecieveBuffer_Head];
			if(DOWNLINKFRAME_SIZE == g_FrameIndex)
			{
				//s_WaitEndOfNewFrame_Count = 0;
				g_FrameIndex = 0;
				g_IsNewFrame = 0;
				g_arr_DownlinkFrame[g_DownlinkFrame_FIFO_End] = *((SDE15_DownlinkFrame_Generic_TypeDef*)(g_NewFrame));
				g_DownlinkFrame_FIFO_End ++;
				if(DOWNLINKFRAME_FIFO_SIZE == g_DownlinkFrame_FIFO_End)
				{
					g_DownlinkFrame_FIFO_End = 0;
				}
			}
		}
		g_UARTRecieveBuffer_Head = Index_Next;
    }
	     /*Fetch one Downlink Frame from the Frame FIFO, if FIFO is not empty*/
	if(g_DownlinkFrame_FIFO_Head != g_DownlinkFrame_FIFO_End)
	{
		DownlinkFrame = g_arr_DownlinkFrame[g_DownlinkFrame_FIFO_Head];
		
	    /*--Downlink Frame decoding---------------------------------*/
		/*Checksum*/
		uint16_t CRC_Temp = 0;
		uint8_t * p_FrameIndex = (uint8_t *)(&DownlinkFrame);
		for(uint32_t i = 0; i < DOWNLINKFRAME_SIZE - 1; i++ )
		{
		  CRC_Temp += p_FrameIndex[i];
		}
		if( ((uint8_t)CRC_Temp) == DownlinkFrame.Checksum)//Check Ok!
		{
		  switch(DownlinkFrame.FrameType)
		  {
			  case FRMTYPE_DOWN_SAMPLE_START_STOP:
				  /*DE15 state switch: sample start or not*/
				  SampleCMD_temp = *(SDE15_DownlinkFrame_SampleCMD_TypeDef*)(&DownlinkFrame);
			     // HAL_UART_Transmit_IT(&huart2,(uint8_t*)&g_arr_DownlinkFrame[g_DownlinkFrame_FIFO_Head],6);
				  if(SampleCMD_temp.StartORStop == SAMPLE_START)
				  {
					g_e_de15_state = DE15_STATE_SAMPLE;
				  }
				  else
				  {
					g_e_de15_state = DE15_STATE_NON_SAMPLE;
				  }
				  break;
			  case FRMTYPE_DOWN_FORCETORST:
                  break;
			  case FRMTYPE_DOWN_INQUIRE:							
               /*Calculate the Checksum*/

					CRCCode = 0;
					uint8_t * p_UpFrame;
					p_UpFrame = (uint8_t *)(&g_t_uplfrm_fdbck);
					for(uint32_t i = 0; i < (UPLINKFRAME_SIZE - 6); i++)
					{
						CRCCode += p_UpFrame[i];
					}
              g_t_uplfrm_fdbck.Checksum = (uint8_t)(CRCCode&0x00FF);
              
	      	  HAL_UART_Transmit_IT(&huart2, (uint8_t *)&g_t_uplfrm_fdbck, 33);					
              /*Throw this ECGData Frame into the to-be-sent FIFO*/
//              p_t_FrameToStore[g_FrameToStore_FIFO_End++] = *(SDE15_UplinkFrame_Generic_TypeDef*)(&g_t_uplfrm_fdbck);
//              g_FrameToStore_FIFO_End = (UPLINKFRAME_FIFO_SIZE == g_FrameToStore_FIFO_End)?(0):(g_FrameToStore_FIFO_End);
                  break;
			  case FRMTYPE_UPDATE://
				  break;
			  
			   default:
				  break;
			  }
		  }
		g_DownlinkFrame_FIFO_Head ++;
		if(DOWNLINKFRAME_FIFO_SIZE == g_DownlinkFrame_FIFO_Head)
		{
			g_DownlinkFrame_FIFO_Head = 0;
		}
	}


}
